Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: parse_float_as_decimal supports scientific notation and Decimal256 #13806

Merged
merged 10 commits into from
Dec 19, 2024

Conversation

jonahgao
Copy link
Member

Which issue does this PR close?

Prerequisite of #12817

Rationale for this change

Parse float string as BigDecimal, then convert it to Decimal128 or Decimal256.

What changes are included in this PR?

Are these changes tested?

Yes

Are there any user-facing changes?

No breaking changes

@github-actions github-actions bot added sql SQL Planner sqllogictest SQL Logic Tests (.slt) labels Dec 17, 2024
select 123456789.0123456789012345678901234567890,
arrow_typeof(123456789.0123456789012345678901234567890)
----
123456789.012345678901 Decimal256(40, 31)
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Display is incomplete due to rounding in sqllogictest

// No decimal point, keep as is
(trimmed.len(), 0, Cow::Borrowed(trimmed))
};
/// Callers ensure the value is within i256 range
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Don't have to, the function is fallible

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I reorganized it and tried to clarify it in 49a4e0a

datafusion/sql/src/expr/value.rs Show resolved Hide resolved
scale as i8,
)))
} else if precision <= DECIMAL256_MAX_PRECISION as u64 {
let val = bigint_to_i256(int_val)?;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

either add comment like above (// Failures are unexpected here as we have already checked the precision), or handle error nicely.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done in 49a4e0a

datafusion/sql/src/expr/value.rs Show resolved Hide resolved
Copy link
Member

@findepi findepi left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice!

};
/// Returns None if the value can't be converted to i256.
/// Modified from <https://github.com/apache/arrow-rs/blob/c4dbf0d8af6ca5a19b8b2ea777da3c276807fc5e/arrow-buffer/src/bigint/mod.rs#L303>
fn bigint_to_i256(v: &BigInt) -> Option<i256> {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

please add unit tests for this function

it should be easy since both BigInt and i256 can convert to/from str

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added, thank you @findepi


let number = replaced_str.parse::<i128>().map_err(|e| {
fn parse_decimal(unsigned_number: &str, negative: bool) -> Result<Expr> {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please add unit tests for this function, to exercise bound checks.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think the new SLT tests have covered them, but please remind me if I've overlooked anything

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

they likely do, but i find it valuable to have unit tests, especially for a code which is well isolated (easy to unit tests) and has so many IFs (valuable to unit test).

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Make sense. Added in 2077749

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

thanks!

@findepi
Copy link
Member

findepi commented Dec 18, 2024

shipit

@jonahgao jonahgao merged commit b7fb32a into apache:main Dec 19, 2024
27 checks passed
@jonahgao
Copy link
Member Author

Thank you @findepi for the review

@jonahgao jonahgao deleted the parse_decimal branch December 19, 2024 01:34
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
sql SQL Planner sqllogictest SQL Logic Tests (.slt)
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants